package edu.mtu.citizenscience.cslocationlestener;

import java.util.Timer;
import java.util.TimerTask;

import com.androidquery.AQuery;

import edu.mtu.citizenscience.gpsservice.CSGpsService;
import edu.mtu.citizenscience.gpsservice.CSLocationListener;
import edu.mtu.citizenscience.gpsservice.CSLocationListenerConnection;
import edu.mtu.citizenscience.gpsservice.CSLocationListenerContainer;

import android.location.Location;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

/*
 * This activity demonstrates getting a location and using CSLocationListener.
 * A button simulates saving a location. If the location is know it saves. 
 * If the location is unknown then it toast the user the first time telling user
 * that there is not a fix. A second press will save the unknow location.
 */
public class DisplayLocation extends Activity implements CSLocationListenerContainer {
	private final String CLASS_NAME = "DisplayLocation";
	private final boolean DEBUG = true;
	
	private AQuery aq;
	
	/* Class for Location Listener Service */
	private CSLocationListener locationListener; // the service
	private CSLocationListenerConnection mConnection; // the connection
	
	private Timer timer; 
	private boolean activityRunning = false; // Switch to indicate that the activity is running this occurs after onResume()

	private boolean isFixed = false; // boolean for if the position is know or unknown
	private boolean toastedNotFixed = false; // counts for number not fixed toast
	    
	 /*
	  * TimerTask
	  */
	class TimeUp extends TimerTask 
	{
		@Override
		public void run() 
		{
			DisplayLocation.this.findViewById(R.id.display_location_layout).post
			(
				new Runnable()
			    {
					public void run()
					{
						updateLocation();
						timer.schedule(new TimeUp(), 1000);
					}
			    }
			);
		}
	}
	
	
	/*
	 * The Basic Activity methods
	 */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (this.DEBUG) Log.d(this.CLASS_NAME, "onCreate");  
        
        setContentView(R.layout.activity_display_loaction);  
               
        /* Start binding */
        // We want this service to run immediately, so we call it in onCreate.	
        // make the binder-connection
        mConnection = new CSLocationListenerConnection(this);
        Intent intent = new Intent(this, CSGpsService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
        
        this.aq = new AQuery(this); // the android-query library object
        
        this.aq.id(R.id.saveLocationButton).clicked(this, "onSaveLocationClicked"); 
    }
    
    @Override
    protected void onStart() {
        super.onStart();      
    }
    

    @Override
    protected void onResume() 
    {
        super.onResume(); 
        if (this.DEBUG) Log.d(this.CLASS_NAME, "onResume"); 
        
        this.timer = new Timer();
        this.timer.schedule(new TimeUp(), 1000);   
        // The connection happens some time after onResume,
        // also no need to start the locationListener, the service will do that.
        // Set tight updates will have to happen with this activity is running,
        // determined by the flag activityRunning
    }
    
    @Override
    protected void onPause()
    {
    	super.onPause();
    	if(this.DEBUG)Log.d(this.CLASS_NAME,"onPause");
    	// Assume if activity not visible then the application does not need tight updates
    	if(this.mConnection.isBound())
    	{
    		this.locationListener.setLooseUpdates();
    		this.activityRunning = false; // the application is not running. 
    		// Setting this will cause tight updates when this activity runs again.
    	}
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if(this.DEBUG)Log.d(this.CLASS_NAME,"onStop");
    }
    
    @Override
    protected void onDestroy()
    {
    	super.onDestroy();
    	if (this.DEBUG)Log.d(this.CLASS_NAME, "onDestroy");
    	// no need to stop locationListener the service will do that
        // Unbind from the service
        if (this.mConnection.isBound()) unbindService(mConnection);
    }
    
   public void updateLocation(){
	   // Check for binding before for first use.
	   // If never bind suspect manifest error. 
	   if(!activityRunning){
		   activityRunning=true;
		   if(this.DEBUG)Log.d(this.CLASS_NAME,"activity running");
		   /*
		    * Want to make this call call once,
		    * but connection is not guaranteed until after the activity is running
		    */
		   this.locationListener.setTightUpdates(); 
	   }
	   if(this.mConnection.isBound())
	   {    
		   Location location = this.locationListener.getCurrentLocation();
		   updateLocation(location);
	   }
   }

	public void updateLocation(Location location) {
		if(this.DEBUG) Log.d(this.CLASS_NAME,"updateLocation");

		if (location != null)
		{
	    	this.aq.id(R.id.time).text(Long.toString(location.getTime()));
			this.aq.id(R.id.latitude).text(Double.toString(location.getLatitude()));
			this.aq.id(R.id.longitude).text(Double.toString(location.getLongitude()));
			this.aq.id(R.id.accuracy).text(Float.toString(location.getAccuracy()));	
			this.isFixed = true;
		}
		else // location is null, so unknown
		{
			this.aq.id(R.id.time).text("unknown");
			this.aq.id(R.id.latitude).text("unknown");
			this.aq.id(R.id.longitude).text("unknown");
			this.aq.id(R.id.accuracy).text("unknown");
			this.isFixed = false;
		}
	}
	
	public void onSaveLocationClicked(View button){
    	CharSequence text;
		if(isFixed || toastedNotFixed)
		{
			text = "Saving position";
			this.toastedNotFixed = false;
		}
		else
		{
			text = "Position is not fixed. If you want to save positon any way tap save again.";
			this.toastedNotFixed = true;
		}	
		Toast toast = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT);
    	toast.show();
	}

	@Override
	public CSLocationListener getCSLocationListener() { return this.locationListener;}
	@Override
	public void setCSLocationListner(CSLocationListener locationListener) { this.locationListener = locationListener;}
  
}
